Maeiee Weekly No.9:在红米 9A 上运行 Droidian 系统
介绍
Droidian 是一种 GNU/Linux 发行版,基于 Mobian。Mobian 是一种基于 Debian 的发行版。Droidian 底层使用了著名的 libhybris 、halium 开源技术。
本文将介绍如何在红米 9A 上安装并运行 Droidian 系统。如果你也对在手机上运行 GNU/Linux 感兴趣,那不要错过这篇文章。
注:在 Weekly No.8 中介绍了 Android 自定义 ROM 的基础知识,本篇是对上一篇的持续深入探索。建议刚入门的小伙伴先阅读 No.8 后再阅读本篇。另外,本文的安装方法对红米 9C 也适用。
效果赏析
首先先来欣赏下最终效果,运行着 Droidian 的红米 9A 😄
完整 Debian GNU/Linux 系统体验 | 运行 Emacs 效果 |
---|---|
发行版信息 | 基于 Gnome 的桌面环境 |
移动端优化的火狐浏览器 | 任务管理器 |
系统内存占用 | 系统信息 |
安装过程
效果是不是很酷炫!如何安装呢?本节介绍红米 9A 机型的 Droidian 具体的安装过程。
对于 Android 手机来说,由于软硬件缺乏统一标准,安装操作系统不像 PC 那样方便。不通的 Android 机型,都需要进行专门进行适配移植(Porting),前些年流行的 Custom ROM,就是靠许多大神一个个机型适配而来的。
从 ROM 角度来看,Droidian 也属于一种自定义 ROM。本文的机缘巧合,是我发现 Bardia 大佬发布了对红米 9A 的 Droidian 移植(Droidian on dandelion/angelica),网页中包含了详尽的安装方法。
下文中是我基于 Droidian on dandelion/angelica 的实践过程,其中有一些不同的地方,主要是 rootfs 下载地址,其它主体流程是一致的。
注:下面的安装方法 以 Redmi 9A dandelion 设备为准,Redmi 9C angelica 需要下载的文件是不同的,具体读者可自行参照 Droidian on dandelion/angelica。
文件准备
首先准备系统安装所需的文件:
文件 | 作用 | 下载方式 |
---|---|---|
boot-dandelion.img | 启动分区,包含内核 Kernel | Droidian on dandelion/angelica |
dtbo-dandelion.img | 设备特有的配置文件 | |
vbmeta-dandelion.img | 启动验证 | |
OrangeFox-R11-garden-droidian.img | 定制 recovery | |
Droidian bookworm (snapshot 24 - 2022-08-04):正式版
nightly:每日构建版 |
rootfs,两个版本任选其一
选择 api29-armhf 的产物 |
Releases · droidian-images/droidian |
adaptation-droidian-garden.zip | rootfs 包是通用镜像,直接是跑不起来的
adaptation 在通用镜像基础上,进行额外机型适配 |
Droidian on dandelion/angelica |
fastboot 刷入镜像
手机重启进入 fastboot。
刷入启动镜像:
[maxiee@maxiee-hpbook Drodian]$ fastboot flash boot boot-dandelion.img
Sending 'boot' (24616 KB) OKAY [ 0.615s]
Writing 'boot' OKAY [ 0.340s]
Finished. Total time: 0.967s
刷入 dtbo:
[maxiee@maxiee-hpbook Drodian]$ fastboot flash dtbo dtbo-dandelion.img
Sending 'dtbo' (114 KB) OKAY [ 0.008s]
Writing 'dtbo' OKAY [ 0.008s]
Finished. Total time: 0.018s
刷入 vbmeta 同时关闭验证:
[maxiee@maxiee-hpbook Drodian]$ fastboot --disable-verity --disable-verification flash vbmeta vbmeta-dandelion.img
Rewriting vbmeta struct at offset: 0
Sending 'vbmeta' (4 KB) OKAY [ 0.005s]
Writing 'vbmeta' OKAY [ 0.006s]
Finished. Total time: 0.012s
官方指南中有一步是刷入 OrangeFox,因为我已经提前刷入了,这一步跳过。 对 userdata 分区进行格式化:
[maxiee@maxiee-hpbook Drodian]$ fastboot format:ext4 userdata
Warning: userdata type is f2fs, but ext4 was requested for formatting.
mke2fs 1.46.2 (28-Feb-2021)
Creating filesystem with 13579515 4k blocks and 3399680 inodes
Filesystem UUID: d4d71f17-2520-433f-8b04-c3c457fcbe58
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424
Allocating group tables: done
Writing inode tables: done
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done
Sending 'userdata' (4665 KB) OKAY [ 0.120s]
Writing 'userdata' OKAY [ 0.088s]
Finished. Total time: 0.254s
recovery sideload
所谓 sideload 包,都是需要刷入 rootfs 里面的。主要包含以下类型:
- rootfs Drodian 自身系统
- Adaption Bundle:设备专属的 bundle(设备相关设置等等)
之后重启进入 recovery:
[maxiee@maxiee-hpbook ~]$ fastboot reboot recovery
Rebooting into recovery OKAY [ 0.001s]
Finished. Total time: 0.151s
进入 OrangeFox 的 Sideload 模式。分别刷入:
[maxiee@maxiee-hpbook Drodian]$ adb sideload droidian-OFFICIAL-phosh-phone-rootfs-api29-armhf-nightly_20220808.zip
serving: 'droidian-OFFICIAL-phosh-phone-rootfs-api29-armhf-nightly_20220808.zip' (~47%) adb: failed to read command: Success
[maxiee@maxiee-hpbook Drodian]$ adb sideload adaptation-droidian-garden.zip
Total xfer: 1.01x
注意:rootfs 在 sideload 时候进度到了 47% 会误报,其实已经是成功的。
之后重启设备。如果没有出意外的话,就能够进入系统了!
概念介绍
有了 Weekly 8 的基础之后,上面的步骤实践起来还是很快的。虽然系统跑起来了,但是其中的很多概念,还是有些陌生。
在本节中,对一些相关的概念来进行介绍。
boot.img 解包(unpack)
boot.img 采用的是一种 Android 特有的镜像格式,需要通过专门工具进行构建。AOSP 里提供了构建工具,但是没有提供解包工具。CyanogenMod 提供了一个解包工具 unpackbootimg,能够解开 boot.img,此类工具还有很多,参见下方文章。
注:《rom flashing - How to unpack and edit boot.img for ROM porting? - Android Enthusiasts Stack Exchange》:文章提到了很多解包工具。unpackbootimg 的详细使用。使用 mkbootimg 重新打包。
Rootfs
打开终端运行 mount 命令,显示根目录(/)的文件系统类型是 rootfs,rootfs 是什么呢?rootfs 是 initramfs,即在启动时加载到内存中的文件系统。该文件系统在内核编译时生成。
Android rootfs 和桌面发行版的 rootfs 有区别:
- 大多数桌面系统的 initramfs 很小,只包含必要程序,随后会加载真正的根文件系统,挂载到(/)上,并替换调 initramfs
- Android 等嵌入式系统,只有一次 initramfs 加载。并且 initramfs 中只有 /init 和 adbd 以及少量配置。
如何修改呢?解压 cpio 包,进行修改,然后再次打包。如果是在 Android 设备上直接修改,需要 root 权限。
Halium
前面 Droidian 的介绍中,提到它基于 Halium 开源技术,Halium 是什么呢?
Halium 是一个合作项目,旨在为在预装 Android 的移动设备上运行 GNU/Linux 的项目统一硬件抽象层。 怎么理解呢?
Android 系统尽管基于 Linux 内核,但并没有完全按照 Linux 的方式来,而是在 Linux 之外,又搞了一大套,变成了 Android 内核,这相当于对 Linux 内核进行了魔改,而魔改之后变得不通用了,比如没有使用 GLibc,而是使用了 bionic 作为标准库。
Halium 相当于对厂商开源内核的又一次包装,将魔改后的内核重新变成通用的 GNU/Linux 内核。
前面说道,Android 机型适配每个机型都要适配一次,Halium 也是如此,这是一个体力活。因此对于爱折腾的小伙伴来说,可以多关注下 Halium、PostmarketOS、Ubuntu Touch 支持的机型,可玩性更高一些。比如红米2,二手只要五六十块,也能运行 GNU/Linux,同时还能更换电池。
Halium 包含三部分:
- Linux 内核:由厂商提供的魔改内核,通常是脱离 mainline 的
- 用于与硬件打交道的 Android 服务:基于 Halium 的 GNU/Linux 系统中,还是通过这些 Android 服务与硬件打交道
- Libhybris:Libhybris 是一个Android兼容层,允许用bionic(Android)libc 编译的库被用不同 libc(最初是 glibc,在 postmarketOS 情况下是 musl)构建的应用程序加载。
GSI(Generic System Image)
在 Weekly8 中有提到过 GSI,通用系统镜像,能够跨机型使用统一份系统镜像,解决 Android 系统的碎片化问题。Droidian
Droidian 也基于 GSI 提供了通用镜像,供支持 GSI 的设备刷入。
在上面的安装过程中可以看到,nightly rootfs 镜像就是 GSI 镜像,如果只刷这一个,设备是跑不起来的。还要再刷 adaption,以通用 GSI + 专用 adaption 的方式完成具体机型的运行。
内核编译
不同设备的 Android Linux 内核是不同的,这需要厂商根据开源协议进行开源。像红米 9A 是开源的,并且有许多大佬做了一些维护。但也有的设备违背了协议,不开源内核源码,如果不开源,就没法折腾了。
对于 Droidian 来说,有一个适配 Droidian 的定制内核(基于 Halium),再加上 GSI 镜像,再加上 adaption 着三部分即可。
值得一提的,文档中说 Droidian 使用了一种不同的方式来编译内核。优势是可以自由分发,同时可以通过 APT 升级内核。
注:《porting-guide/kernel-compilation.md at master · droidian/porting-guide · GitHub》
注2:具体参考 Halium 的内核移植手册《Build Halium — Halium documentation》
Boot image
boot.img 是 Android 的启动分区镜像,内含 Linux 内核和 rootfs 等启动时的关键组件。
内核编译成功后,会有多种产物产出:首先是 boot.img,同时将其打成一个 Debian 包(linux-bootimage-VERSION-VENDOR-DEVICE)。其中,内核镜像里面已经集成了通用 Halium initramfs。
Droidian-MT6765/MT6762
Droidian 的移植者专门为红米 9A 适配建立的仓库,地址。其中包含以下仓库:
- adaptation-droidian-garden:adaptation files for Redmi 9A codenamed dandelion and Redmi 9C codenamed angelica (and possibly 9i, 9AT, 10A)
- kernel-xiaomi-mt6765
- device-page
- UT_Droidian_Dualboot
- adaptation-garden-script
Droidian 日常使用
系统升级
sudo apt update
sudo apt upgrade
发行版代号
Droidian 最近刚刚发布了一个新的大版本,代号为 Bookworm:
- Bookworm:新
- Bullseye:旧
如何提升续航
看群里大佬说的:写一个脚本,锁屏后将 governor 切换到 powersave。电池能够撑一天半到两天。
电池鼓包问题
这是微博小伙伴反馈的:如果插电长时间重载运行电池可能会鼓包。
其中,可能有两个原因:
- 持续充放电:可以写个脚本,充电到某个程度后不再充电,改为只走电源
- 高温:可以考虑加一个散热背夹,用于桌面高强度使用
我很佩服这个小伙伴,因为这说明真的是把设备当成生产力工具用起来了。
Droidian Devtools
供 Porter 使用的实用开发工具,nightly 中不提供,因为他们需要嵌入到 rootfs 中。
通过 USB 线进行调试
Droidian Devtools 包中默认开启了 USB 网络,刷入 Devtools 包后,可以通过 usb 线 ssh 连接设备:
ssh droidian@设备USB IP
注:小米平板4上的Debian Linux(Droidian)方便日常使用的一些设置_HandsomeHacker的博客-CSDN博客_小米平板4安装linux
ssh 不生效时如何查看日志
telnet 192.168.2.15 23
Linux 知识
这次折腾 Droidian,让我学到了不少 Linux 知识。
- wlroots:是一个模块化的 Wayland 合成器库。
- wlr-randr:一个管理 wayland 合成器输出的软件。
- batman:用于 droidian 的电池管理服务。
- Angelfish:一个用于移动端的浏览器。
- libgbinder
- binder 的 GLib 接口。关键特性:
- 继承 GLib 时间循环
- 运行时检测 32位、64位内核
- 异步事务不阻塞事件线程
- 稳定的服务管理器和底层事务 API
- GitHub - mer-hybris/libgbinder: GLib-style interface to binder
- binder 的 GLib 接口。关键特性:
- Pastebins:交流的时候需要发送一些日志。
哪些不工作
虽然效果图中看着很美好,但是实际使用体验并不完美,很多功能是不工作或者勉强能工作的状态。Droidian on dandelion/angelica 中列出了一些哪些工程正常,哪些不正常。
在我的实践中,主要是遇到了2个:触摸屏不正常(已解决)、电源键不正常(未解决)。
触摸屏
最初的几天触摸屏是不生效的,我只能连接一个鼠标来用。为什么不生效呢?触摸屏属于驱动,位于哪里呢?是 Linux Kernel 里的驱动,还是 HAL 里的驱动?是位于 boot.img 里面,还是 rootfs 里面呢?这一点我还不知道。
为了排查不生效的问题,首先查看日志:
sudo journalctl -b 0 --no-pager |grep pho
找到了内核驱动加载过程中的报错(最后发现与此无关): 查看系统启动日志,发现触摸屏是加载出来了,但是固件加载失败:
fts_ts spi32763.0: Direct firmware load for focaltech_ts_fw_helitai.bin failed with error -2
查看 vendor 目录下的固件,发现确实没有这个文件:
droidian@M2006C3LG:~$ cd /vendor/firmware/
droidian@M2006C3LG:/vendor/firmware$ ls -la
total 3316
drwxr-xr-x. 2 root 2000 4096 Dec 31 2008 .
drwxr-xr-x 1 root root 4096 Aug 9 11:52 ..
-rw-r--r--. 1 root root 131072 Dec 31 2008 focaltech_aa_ts_fw_helitai.bin
-rw-r--r--. 1 root root 131072 Dec 31 2008 focaltech_ab_ts_fw_helitai.bin
但是有一个 aa 一个 ab,有点可以。
我花了好几天时间,思考怎么修改 vendor 分区的文件,将 focaltech_aa_ts_fw_helitai.bin 复制一份称为 focaltech_ts_fw_helitai.bin。后来又思考怎么修改内核的启动参数,通过查阅文档《kernel 空间加载用户空间fw实现原理 - 魅族内核团队》,发现还有 CONFIG_FW_LOADER_USER_HELPER 这个 fallback 机制,当固件加载不出来的时候,允许从用户空间加载固件。
最终意外解决了问题,我用 Droidian on dandelion/angelica 提供的 PBRP Recovery 替换了我之前的 Official OrangeFox,重启进入系统后触摸就正常了。
我对比了前后的内核启动日志,发现两次启动的过程是不同的,目前还不知道具体的区别原因是什么。
电源键不工作
电源键问题是电源键无法唤起屏幕,设备休眠会自动息屏,息屏之后就起不来了。
我也请教了 Droidian on dandelion/angelica 的维护者 FakeShell 大佬 ,得到回复:
@FakeShell:Yes i am aware of this issue. We had a workaround when I was porting dandelion/angelica back in the day but it does not work anymore. The issue is not specific to this device, same issue with rosemary (Redmi Note 10S) and VollaPhone. Apparently it is an issue with MTK devices.
貌似整个 MTK 设备都遇到了同样的问题,在最新的 Bookworm 发行版上电源有问题。按下电源建 libinput 会有反应的。
开源社区交流
这次折腾还有一个收获,浅浅的参与了以下开源社区,比如:
- 挖掘官方 TG 群(还有 Matrix 消息同步):看大家纯粹讨论技术,学到很多,这些知识平时在文章里很难见到
- 跟 FakeShell 大佬每日夜聊:Screen touching and power button not work on Dandelion · Issue #1 · droidian-mt6765/adaptation-droidian-garden
- 技术人都很 nice,大家因为兴趣相聚也很单纯,也不会嫌我 Low。能力大的出大力,能力小的出小力。
- 答应了测试一下电源键的 Log,下周抽时间搞一下
- 甚至还给 WayDroid 提了个 PR(修了个小 Typo……)
- fix typo in arguments.py by maxiee · Pull Request #461 · waydroid/waydroid
- 翻阅代码的时候看到了就随手给修了
- 修 Typo 算是参与社区的入门新手任务了……
Weekly10 预告
Weekly8、Weekly9 两周改变形式之后,确实硬核了不少,对我的磨炼也加强了许多。
这些内容都是在工作外的业务时间展开的,也确实比较累人。
下周 Weekly10 准备搞点轻松的。不设定固定主题了,几个事情要做:
- 备份现有工作机里的数据,准备更换开发机,目前看中了小新 Duet 2022 二合一平板
- 新设备我会尝试使用 Win11 + WSLg 作为开发环境,未来可以专门写个主题
- Debug 一下 Droidian 电源键问题
- 看看网上技术文章,像以前那样总结下核心内容
附录
折腾记录
20220808:
droidian-OFFICIAL-phosh-phone-rootfs-api29-armhf-nightly_20220808.zip
触摸屏不好用,电源键不好用。
20220809:
droidian-OFFICIAL-phosh-phone-rootfs-api29-armhf-nightly_20220809.zip
尝试刷入 Devtools:droidian-devtools-api29-armhf_20220804.zip
这俩都刷完之后,开始卡启动屏了。之后按照刷机流程完全重刷,并只刷 nightly_20220809,结果还是卡启动屏。
重新 sideload 20220808.zip。这次没有按照之前流程重刷,而只是 sideload。结果还是卡启动屏。
按照完整流程重刷 20220808.zip。还是卡启动屏。我知道为啥了,因为我 adaptation 没有刷。
20220809 + adaptation 再试一下。这次能够正常启动了,看来是 adaptation 的缘故。
20220810:
今天继续思考触摸屏不好用的问题。
Droidian 红米 9A 适配官网 提到一种刷入 PBRP 来运行 adaptation script 的方法,我准备试一下。下载 PBRP 并刷入。
[maxiee@maxiee-hpbook ~]$ fastboot flash recovery /run/media/maxiee/69ac3c9e-8a91-416a-8b1e-389525895c15/Code/RedMi9A/Drodian/PBRP-3.1.0.img
Sending 'recovery' (65536 KB) OKAY [ 1.635s]
Writing 'recovery' OKAY [ 0.884s]
Finished. Total time: 2.520s
[maxiee@maxiee-hpbook ~]$ fastboot reboot recovery
Rebooting into recovery OKAY [ 0.001s]
Finished. Total time: 0.102s
很神奇,刷完 PBRP 之后重启,触摸屏就好了。
Droidian 其他机型适配
从其他机型中多手机一些信息:
多对比上面机型的安装过程,以及底下的评论。
网络资源
Drodian 官方文档
porting-guide/debugging-tips.md at master · droidian/porting-guide · GitHub
Supported Devices | Droidian:Droidian 支持的机型
官方有电报群,无法访问的话,还有 Matrix 消息同步。聊天历史,可惜没有图。
红米 9A 适配相关文档
其它文章
小米平板4上的Debian Linux(Droidian)方便日常使用的一些设置_HandsomeHacker的博客-CSDN博客_小米平板4安装linux
推荐这个老哥的博客,也很能折腾 HandsomeHacker。Halium 9 尝鲜 -- 在小米平板4上的移植 (七)_HandsomeHacker的博客-CSDN博客待阅读